/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Copyright 2002-2003 by Mark Wolgemuth, All rights reserved.             */
/* Copyright 2002-2003 by Employease, Inc.  All rights reserved.           */
/*                                                                         */
/* Redistribution and use in source and binary forms, with or without      */
/* modification, are permitted provided that the following conditions      */
/* are met:                                                                */
/*                                                                         */
/*    1. Redistributions of source code must retain the above copyright    */
/* notice, this list of conditions and the following disclaimer.           */
/*    2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the     */
/* documentation and/or other materials provided with the distribution.    */
/*                                                                         */
/* THIS SOFTWARE IS PROVIDED BY THE MOD_ATHENA PROJECT ``AS IS'' AND ANY   */
/* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE       */
/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR      */
/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR        */
/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,   */
/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,     */
/* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR      */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY     */
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT            */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "athd.h"

const char *
athd_conf_prop_name(athd_conf *conf, char *arg, char *pararg)
{
    char *name;
    if (arg)
	name = apr_pstrdup(conf->pool, arg);
    else
      {
	  name = apr_pcalloc(conf->pool, sizeof(char[APRMAXHOSTLEN + 1]));
	  apr_gethostname(name, APRMAXHOSTLEN + 1, conf->pool);
      }
    conf->server_name = name;
    return NULL;
}

const char *
athd_conf_prop_debug(athd_conf *conf, char *arg, char *pararg)
{
    int lvl;
    if (!strcasecmp(arg, "core"))
	lvl = ATHD_CORE;
    else if (!strcasecmp(arg, "crit"))
	lvl = ATHD_CRIT;
    else if (!strcasecmp(arg, "warn"))
	lvl = ATHD_WARN;
    else if (!strcasecmp(arg, "note"))
	lvl = ATHD_NOTE;
    else if (!strcasecmp(arg, "info"))
	lvl = ATHD_INFO;
    else if (!strcasecmp(arg, "debug"))
	lvl = ATHD_DEBUG;
    else if (!strcasecmp(arg, "devel"))
	lvl = ATHD_DEVEL;
    else
	lvl = atoi(arg);
    conf->debug = lvl;
    return NULL;
}

const char *
athd_conf_prop_shm(athd_conf *conf, char *arg, char *pararg)
{
    char *path;
    if (arg)
	path = apr_pstrdup(conf->pool, arg);
    conf->use_shm = path;
    return NULL;
}

const char * 
athd_conf_prop_apconf(athd_conf *conf, char *arg, char *pararg)
{
    char *path;
    if (arg)
	path = apr_pstrdup(conf->pool, arg);
    conf->use_apconf = path;
    return NULL;
}

const char * 
athd_conf_prop_uid(athd_conf *conf, char *arg, char *pararg)
{
    int rv;
    char *msg = NULL;
    if (arg)
      {
	  athd_log(ATHD_WARN, "Config: setuid not implemented yet");
	  rv = apr_uid_get(&conf->uid, &conf->gid, arg, conf->pool);
	  if (rv)
	    {
		char *str_err = apr_pcalloc(conf->pool, 
					    sizeof(char[ATHD_MAX_STRERR]));
		apr_strerror(rv, str_err, ATHD_MAX_STRERR);
		msg = str_err;
	    }
      }
    else
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char * 
athd_conf_prop_gid(athd_conf *conf, char *arg, char *pararg)
{
    int rv;
    char *msg = NULL;
    if (arg)
      {
	  athd_log(ATHD_WARN, "Config: setgid not implemented yet");
	  rv = apr_gid_get(&conf->gid, arg, conf->pool);
	  if (rv)
	    {
		char *str_err = apr_pcalloc(conf->pool, 
					    sizeof(char[ATHD_MAX_STRERR]));
		apr_strerror(rv, str_err, ATHD_MAX_STRERR);
		return str_err;
	    }
	  if (conf->uid == -1)
	      msg = ATHD_ERR_GID;
      }
    else
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char * 
athd_conf_prop_port(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    if (arg)
      {
	  switch (*arg)
	    {
	    case 'o': /* off */
	    case 'O': /* Off */ 
	    case '-': /* - or -1, also off */
		conf->port = 0;
		break;
	    default:
		conf->port = atoi(arg);
	    }
      }
    else
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char * 
athd_conf_prop_pidfile(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    if (arg)
	conf->pidfile = apr_pstrdup(conf->pool, arg);
    else
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char * 
athd_conf_prop_logfile(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    if (arg)
      {
	  if (conf->syslog_fac == -1)
	    {
		if (!strncasecmp(arg, "daemon", 6))
		    conf->syslog_fac = LOG_DAEMON;
		else if (!strncasecmp(arg, "user", 4))
		    conf->syslog_fac = LOG_USER;
		else if (!strncasecmp(arg, "local0", 6))
		    conf->syslog_fac = LOG_LOCAL0;
		else if (!strncasecmp(arg, "local1", 6))
		    conf->syslog_fac = LOG_LOCAL1;
		else if (!strncasecmp(arg, "local2", 6))
		    conf->syslog_fac = LOG_LOCAL2;
		else if (!strncasecmp(arg, "local3", 6))
		    conf->syslog_fac = LOG_LOCAL3;
		else
		    msg = ATHD_ERR_BADLOGFAC;
	    }
	  else if ((*arg) && ((*arg) == '|'))
	    {
		arg++;
		if ((arg) && (!strncasecmp(arg, "syslog", 6)))
		  {
		      conf->syslog_fac = -1;
		      conf->logfile = NULL;
		  }
	    }
	  else
	      conf->logfile = apr_pstrdup(conf->pool, arg);
      }
    else
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char *
athd_conf_prop_loglock(athd_conf *conf, char *arg, char *pararg)
{
    char *path;
    if (arg)
	path = apr_pstrdup(conf->pool, arg);
    conf->log_lock_path = path;
    return NULL;
}

const char * 
athd_conf_prop_shell(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    if (arg)
	conf->os->path_shell = apr_pstrdup(conf->pool, arg);
    else
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char * 
athd_conf_prop_sendmail(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    if (arg)
      {
	  if (conf->os->path_sendmail)
	      conf->os->path_sendmail = apr_pstrcat(conf->pool, 
						    conf->os->path_sendmail,
						    " ", arg, NULL);
	  else
	      conf->os->path_sendmail = apr_pstrdup(conf->pool, arg);
      }
    else
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char *     
athd_conf_prop_ip(athd_conf *cf, char *arg, char *parg)
{
    char *msg = NULL;
    if (arg)
	cf->ip_lb = ath_flag_is_on(arg);
    else 
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char *     
athd_conf_prop_ipport(athd_conf *cf, char *arg, char *parg)
{
    char *msg = NULL;
    if (arg) 
	cf->ip_divertport = atoi(arg);
    else 
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char *     
athd_conf_prop_ipdeny(athd_conf *cf, char *arg, char *parg)
{
    char *msg = NULL;
    if (arg)    
	cf->ip_deny = ath_flag_is_on(arg);
    else 
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char *    
athd_conf_prop_ipsock(athd_conf *cf, char *arg, char *parg)
{
    char *msg = NULL;
    if (arg)    
	cf->ip_sockets = ath_flag_is_on(arg);
    else 
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char *     
athd_conf_prop_ipmapfarm(athd_conf *cf, char *arg, char *parg)
{
    char *name, *str_tok, *inter;
    int farmport = -1;
    int physport = -1;
    char *sep = " \t,";
    char *msg = NULL;

    if (arg)
      {
	  name = apr_strtok(arg, sep, &inter);
	  if (name)
	    {
		str_tok = apr_strtok(NULL, sep, &inter);
		farmport = atoi(str_tok);
	    }
	  if (str_tok)
	    {
		str_tok = apr_strtok(NULL, sep, &inter);
		physport = atoi(str_tok);
	    }
	  if ((!name) || (farmport < 0) || (physport < 0))
	      msg = "ERROR: Incomplete farm to phys port mapping";
	  else
	      athd_conf_ip_farm_add(cf, name, farmport, physport);
      }
    else
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char *     
athd_conf_prop_ipfarms(athd_conf *cf, char *arg, char *parg)
{
    char *msg = NULL;
    if (arg)
      {
	  char *str_tok, *inter;
	  char *sep = " \t,";
	  str_tok = apr_strtok(arg, sep, &inter);
	  while (strtok)
	    {
		athd_conf_ip_farm_add(cf, str_tok, -1, -1);
		str_tok = apr_strtok(NULL, sep, &inter);
	    }
      }
    else
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char * 
athd_conf_prop_statspulse(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    if (arg)
	conf->stats_pulse = atoi(arg);
    else
	msg = ATHD_ERR_MISSARG;
    return msg;
}

const char * 
athd_conf_prop_eng(athd_conf *conf, char *arg, char *pararg)
{
    char *name;
    char *msg = NULL;
    /* this should not actually be error 
       secondaries get implicitly declared
    */
    /*     if (athd_engine_for_name(conf->engines, arg)) */
    /*         msg = ATHD_ERR_ENGEXST; */
    if (!(athd_engine_for_name(conf->engines, arg)))
      {
          name = apr_pstrdup(conf->pool, arg);
          athd_engine_add_by_name(conf, name);
      }
    return msg;
}

const char * 
athd_conf_prop_engkeep(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    athd_engine *engine;
    engine = athd_engine_for_name(conf->engines, pararg);
    if (engine == NULL)
	msg = ATHD_ERR_ENGNONE;
    else
      {
	  if (arg)
	      engine->keep_alive = ath_flag_is_on(arg);
	  else
	      msg = ATHD_ERR_MISSARG;
      }
    return msg;
}

const char * 
athd_conf_prop_engqlimit(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    athd_engine *engine;
    engine = athd_engine_for_name(conf->engines, pararg);
    if (engine == NULL)
	msg = ATHD_ERR_ENGNONE;
    else
      {
	  if (arg)
	      engine->request_q_limit = atoi(arg);
	  else
	      msg = ATHD_ERR_MISSARG;
      }
    return msg;
}

const char * 
athd_conf_prop_engpri(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    athd_engine *engine;
    engine = athd_engine_for_name(conf->engines, pararg);
    if (engine == NULL)
	msg = ATHD_ERR_ENGNONE;
    else
      {
	  if (arg)
	      athd_engine_set_url(engine, arg);
	  else
	      msg = ATHD_ERR_MISSARG;
      }
    return msg;
}

const char * 
athd_conf_prop_engsec(athd_conf *conf, char *arg, char *pararg)
{
    char *name_sec;
    char *msg = NULL;
    athd_engine *engine;
    athd_engine *eng_sec;
    engine = athd_engine_for_name(conf->engines, pararg);
    if (engine)
      {
	  if (arg != NULL)
	    {
		if ((eng_sec = athd_engine_for_name(conf->engines, arg))
		    == NULL)
		  {
		      name_sec = apr_pstrdup(conf->pool, arg);
		      eng_sec = athd_engine_add_by_name(conf, name_sec);
		  }
		ath_list_ap_add(conf->pool, engine->secondaries, eng_sec);
	    }
	  else
	      msg = ATHD_ERR_MISSARG;
      }
    else
	msg = ATHD_ERR_ENGNONE;
    return msg;
}

const char * 
athd_conf_prop_engip(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    athd_engine *engine;
    engine = athd_engine_for_name(conf->engines, pararg);
    if (engine == NULL)
	msg = ATHD_ERR_ENGNONE;
    else
      {
	  if (arg)
	      engine->ip_enable = ath_flag_is_on(arg);
	  else
	      msg = ATHD_ERR_MISSARG;
      }
    return msg;
}

const char * 
athd_conf_prop_job(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    if (athd_job_for_name(conf->jobs, arg))
	msg = ATHD_ERR_JOBEXST;
    else
	athd_job_add_by_name(conf, arg);
    return msg;
}

const char * 
athd_conf_prop_jobtype(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    athd_job *job;
    job = athd_job_for_name(conf->jobs, pararg);
    if (job)
      {
	  if (arg)
	      job->type = athd_job_type_from_str(arg);
	  else
	      msg = ATHD_ERR_MISSARG;
      }
    else
	msg = ATHD_ERR_JOBNONE;
    return msg;
}

const char * 
athd_conf_prop_jobfreq(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    athd_job *job;
    job = athd_job_for_name(conf->jobs, pararg);
    if (job)
      {
	  if (arg)
	      job->freq = atoi(arg);
	  else
	      msg = ATHD_ERR_MISSARG;
      }  
    else
	msg = ATHD_ERR_JOBNONE;
    return msg;
}

const char * 
athd_conf_prop_jobmail(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    athd_job *job;
    ASSERT(conf && arg && pararg);
    job = athd_job_for_name(conf->jobs, pararg);
    if (job)
      {
	  if (arg)
	      athd_job_set_mail_on(job, ath_flag_is_on(arg));
	  else
	      msg = ATHD_ERR_MISSARG;
      }  
    else
	msg = ATHD_ERR_JOBNONE;
    return msg;
}

const char * 
athd_conf_prop_jobmailaddr(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    char *mailaddr;
    char *sep = " \t,";
    char *inter;
    athd_job *job;
    job = athd_job_for_name(conf->jobs, pararg);
    if (job)
      {
	  mailaddr = apr_strtok(arg, sep, &inter);
	  if (mailaddr)
	    {	
		while (mailaddr)
		  {
		      athd_job_add_mailaddr(job, mailaddr);
		      mailaddr = apr_strtok(NULL, sep, &inter);
		  }
	    }
	  else
	      msg = ATHD_ERR_MISSARG;
      }  
    else
	msg = ATHD_ERR_JOBNONE;
    return msg;
}

const char * 
athd_conf_prop_jobmailreply(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    athd_job *job;
    ASSERT(conf && arg && pararg);
    job = athd_job_for_name(conf->jobs, pararg);
    if (job)
      {
	  if (arg)
	      athd_job_set_mailreplyto(job, arg);
	  else
	      msg = ATHD_ERR_MISSARG;
      }  
    else
	msg = ATHD_ERR_JOBNONE;
    return msg;

}
const char * 
athd_conf_prop_jobmailrate(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    athd_job *job;
    ASSERT(conf && arg && pararg);
    job = athd_job_for_name(conf->jobs, pararg);
    if (job)
      {
	  if (arg)
	      athd_job_set_mailrate(job, arg);
	  else
	      msg = ATHD_ERR_MISSARG;
      }  
    else
	msg = ATHD_ERR_JOBNONE;
    return msg;

}

const char * 
athd_conf_prop_jobeng(athd_conf *conf, char *arg, char *pararg)
{
    char *msg = NULL;
    athd_job *job;
    job = athd_job_for_name(conf->jobs, pararg);
    if (job)
      {
	  char *engname;
	  char *sep = " \t,";
	  char *inter;
	  engname = apr_strtok(arg, sep, &inter);
	  if (engname)
	    {	
		athd_engine *eng = NULL;
		eng = athd_engine_for_name(conf->engines, engname);
		if (job->engine)
		    msg = ATHD_ERR_ENGOONE;
		else if (eng) 
		    athd_job_add_engine(job, eng);
		else
		    msg = ATHD_ERR_ENGNONE;
	    }
	  else
	      msg = ATHD_ERR_MISSARG;
	  
      }  
    else
	msg = ATHD_ERR_JOBNONE;
    return msg;
}
